<template>
  <el-dialog class="chat-voice" title="语音录制" :visible.sync="visible" width="80%" :before-close="handleClose"
             :append-to-body="true"
  >
    <div v-show="mode=='RECORD'">
      <div class="chat-voice-tip">{{ stateTip }}</div>
      <div>时长: {{ state == 'STOP' ? 0 : parseInt(rc.duration) }}s</div>
    </div>
    <audio v-show="mode=='PLAY'" :src="url" controls ref="audio" @ended="handleStopAudio()"></audio>
    <el-divider content-position="center"></el-divider>
    <el-row class="chat-voice-btn-group">
      <el-button round type="primary" v-show="state=='STOP'" @click="handleStartRecord()">开始录音</el-button>
      <el-button round type="warning" v-show="state=='RUNNING'" @click="handlePauseRecord()">暂停录音</el-button>
      <el-button round type="primary" v-show="state=='PAUSE'" @click="handleResumeRecord()">继续录音</el-button>
      <el-button round type="danger" v-show="state=='RUNNING'||state=='PAUSE'" @click="handleCompleteRecord()">
        结束录音
      </el-button>
      <el-button round type="success" v-show="state=='COMPLETE' && mode!='PLAY'" @click="handlePlayAudio()">播放录音
      </el-button>
      <el-button round type="warning" v-show="state=='COMPLETE' && mode=='PLAY'" @click="handleStopAudio()">停止播放
      </el-button>
      <el-button round type="primary" v-show="state=='COMPLETE'" @click="handleRestartRecord()">重新录音</el-button>
      <el-button round type="primary" v-show="state=='COMPLETE'" @click="handleSendRecord()">立即发送</el-button>
    </el-row>
  </el-dialog>

</template>

<script>
import Recorder from 'js-audio-recorder';
import httpRequest from "@/api/httpRequest";

export default {
  name: 'chatVoice',
  props: {
    visible: {
      type: Boolean
    }
  },
  data() {
    return {
      rc: new Recorder(),
      audio: new Audio(),
      state: 'STOP', // STOP、RUNNING、PAUSE、COMPLETE
      stateTip: "未开始",
      mode: 'RECORD', // RECORD 、PLAY
      duration: 0,
      url: "",
      //限制录音不到1S 提示时间过短 无法发送
      timer: 0, // 计时器变量，单位：秒
      intervalId: null, // 计时器的 ID
      isSending: false, // 是否正在发送语音
    }
  },
  computed: {
    canSend() {
      return this.timer >= 1 && !this.isSending;
    },
  },
  beforeDestroy() {
    clearInterval(this.intervalId); // 组件销毁前清除计时器
  },
  methods: {
    handleClose() {
      // 关闭前清除数据
      this.rc.destroy();
      this.rc = new Recorder();
      this.audio.pause();
      this.mode = 'RECORD';
      this.state = 'STOP';
      this.stateTip = '未开始';
      this.$emit("close");
    },
    handleStartRecord() {
      this.timer = 0;
      this.intervalId = setInterval(() => {
        this.timer++;
      }, 1000);
      this.rc.start().then((stream) => {
        this.state = 'RUNNING';
        this.stateTip = "正在录音...";
      }).catch(error => {
        console.log(error);
        this.$message.error(error);
        console.log(error);
      });


    },
    handlePauseRecord() {
      this.rc.pause();
      this.state = 'PAUSE';
      this.stateTip = "已暂停录音";
    },
    handleResumeRecord() {
      this.rc.resume();
      this.state = 'RUNNING';
      this.stateTip = "正在录音...";
    },
    handleCompleteRecord() {
      this.rc.pause();
      this.state = 'COMPLETE';
      this.stateTip = "已结束录音";
    },
    handlePlayAudio() {
      console.log('开始播放录音')
      let wav = this.rc.getWAVBlob();
      let url = URL.createObjectURL(wav);
      this.$refs.audio.src = url;
      this.$refs.audio.play();
      this.mode = 'PLAY';
    },
    handleStopAudio() {
      console.log(this.$refs.audio);
      this.$refs.audio.pause();
      this.mode = 'RECORD';
    },
    handleRestartRecord() {
      this.rc.destroy();
      this.rc = new Recorder()
      this.rc.start();
      this.state = 'RUNNING';
      this.mode = 'RECORD';
      this.stateTip = "正在录音...";
    },
    handleSendRecord() {
      if (this.rc.duration < 1) {
        this.$toast.fail('录音时间不能少于1S');
        return;
      }
      let wav = this.rc.getWAVBlob();
      let name = new Date().getDate() + '.wav';
      var formData = new window.FormData()
      formData.append('file', wav, name);
      httpRequest({
        url: '/file/upload',
        data: formData,
        method: 'post',
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then((url) => {
        let data = {
          duration: parseInt(this.rc.duration),
          url: url
        }
        this.$emit("send", data);
        this.handleClose();
      })
    }
  }

}
</script>

<style lang="less">
.chat-voice {
  text-align: center;

  .chat-voice-tip {
    font-size: 18px;
  }

  .chat-voice-btn-group {
    margin-bottom: 20px;
  }
}
</style>
